//
//  IMUserManager.m
//  MLIM
//
//  Created by molon on 15/7/5.
//  Copyright (c) 2015年 molon. All rights reserved.
//

#import "IMUserManager.h"
#import "IMUser.h"

NSString * const MLIM_IMUser_UpdateOrAddUsers_Notification = @"com.molon.MLIM_IMUser_UpdateOrAddUsers_Notification";

@interface IMUserManager()

@property (nonatomic, strong) NSMutableDictionary *imUsers;

//当前在请求中的
//一般是  clientIdsSet做key，然后value是block数组
@property (nonatomic, strong) NSMutableDictionary *executingSearchMap;

@end

@implementation IMUserManager

+ (instancetype)manager
{
    static id _sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[[self class] alloc]init];
    });
    return _sharedInstance;
}

#pragma mark - getter
- (NSMutableDictionary *)imUsers
{
    if (!_imUsers) {
        _imUsers = [NSMutableDictionary dictionary];
    }
    return _imUsers;
}

- (NSMutableDictionary *)executingSearchMap
{
    if (!_executingSearchMap) {
        _executingSearchMap = [NSMutableDictionary dictionary];
    }
    return _executingSearchMap;
}

#pragma mark - outcall
//TODO:这里返回的可能和传递进来的个数不一致，可能会多。具体请看代码
- (void)imUsersWithClientIds:(NSSet*)clientIdsSet callback:(IMDictionaryResultBlock)callback
{
    NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity:clientIdsSet.count];
    
    NSMutableSet *newClientIdsSet = [NSMutableSet set];
    for (NSString *clientId in clientIdsSet) {
        IMUser *imUser = self.imUsers[clientId];
        if (!imUser) {
            [newClientIdsSet addObject:clientId];
        }else{
            result[clientId] = imUser;
        }
    }
    if (newClientIdsSet.count<=0) {
        if (callback) {
            callback(result,nil);
        }
        return;
    }
    
    //通过回调获取结果
    NSAssert(self.imUsersSearchBlock, @"必须实现imUsersSearchBlock");
    
    //检测是否有执行中的请求是包含这些clientId的
    for (NSSet *executingClientIdsSet in [self.executingSearchMap allKeys]) {
        if ([newClientIdsSet isSubsetOfSet:executingClientIdsSet]) {
            //直接塞入其对应回调列表，返回即可
            if (callback) {
                NSMutableArray *callbackArray = self.executingSearchMap[executingClientIdsSet];
                [callbackArray addObject:[callback copy]];
            }
            return;
        }
    }
    
    //没有找到正在执行的包含，就重新建立一个请求
    NSMutableArray *callbackArray = [NSMutableArray array];
    if (callback) {
        [callbackArray addObject:[callback copy]];
    }
    self.executingSearchMap[newClientIdsSet] = callbackArray;
    
    IMDictionaryResultBlock block = ^(NSDictionary *dict,NSError *error){
        if (dict.count>0) {
            [self.imUsers setValuesForKeysWithDictionary:dict];
            
            [[NSNotificationCenter defaultCenter]postNotificationName:MLIM_IMUser_UpdateOrAddUsers_Notification object:nil userInfo:@{@"imUsers":dict}];
            
            [result setValuesForKeysWithDictionary:dict];
        }
        
        //检查没有的然后给默认的,但是不存储到imUsers里，这样的话，下一次进到这个方法里的时候也会去请求头像
        for (NSString *clientId in newClientIdsSet) {
            if (!dict[clientId]) {
                IMUser *user = [IMUser new];
                user.clientId = clientId;
                if (self.defaultNameWithClientIdBlock) {
                    user.name = self.defaultNameWithClientIdBlock(clientId);
                }
                if (user.name.length<=0) {
                    user.name = user.clientId;
                }
                result[clientId] = user;
            }
        }
        
        //这里我们忽略这个错误吧，如果为了让体验更好，只能这样做。而最后隔段时间就检测下当前是否有没获取到信息的用户，有的话就自动重新获取
        //找到所有的存储回调，去执行他们，然后删除executingSearchMap里的对应项
        for (IMDictionaryResultBlock aCallback in callbackArray) {
            dispatch_async(dispatch_get_main_queue(), ^{ //发现有callback里可能做了影响callbackArray的操作，引起crash，这里避免下
                aCallback(result,nil);
            });
        }
        
        [self.executingSearchMap removeObjectForKey:newClientIdsSet];
    };
    self.imUsersSearchBlock(newClientIdsSet,block);
}

- (void)imUserWithClientId:(NSString*)clientId callback:(IMUserResultBlock)callback
{
    if (clientId.length<=0) {
        if (callback) {
            //TODO:暂时懒得弄error
            callback(nil,nil);
        }
        return;
    }
    
    [self imUsersWithClientIds:[NSSet setWithObject:clientId] callback:^(NSDictionary *dict, NSError *error) {
        IMUser *imUser = dict[clientId];
        if (callback) {
            callback(imUser,error);
        }
    }];
}

- (void)updateOrAddClientIds:(NSSet*)clientIdsSet callback:(IMBooleanResultBlock)callback
{
    //通过回调获取结果
    NSAssert(self.imUsersSearchBlock, @"必须实现imUsersSearchBlock");
    IMDictionaryResultBlock block = ^(NSDictionary *dict,NSError *error){
        if (dict.count<=0||error) {
            if (callback) {
                callback(NO,error);
            }
            return;
        }
        
        [self.imUsers setValuesForKeysWithDictionary:dict];
        
        [[NSNotificationCenter defaultCenter]postNotificationName:MLIM_IMUser_UpdateOrAddUsers_Notification object:nil userInfo:@{@"imUsers":dict}];
        
//        if (dict.count<clientIdsSet.count) {
//            //TODO: 很多error信息都不完整以后处理吧
//            if (callback) {
//                callback(NO,nil);
//            }
//            return;
//        }
        
        if (callback) {
            callback(YES,error);
        }
    };
    
    self.imUsersSearchBlock(clientIdsSet,block);
}

@end
